package com.atguigu.spzx.product.service.impl;

import com.atguigu.spzx.model.vo.h5.CategoryVo;
import com.atguigu.spzx.product.mapper.CategoryMapper;
import com.atguigu.spzx.product.service.CategoryService;
import jakarta.annotation.Resource;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class CategoryServiceImpl implements CategoryService {
    @Resource
    CategoryMapper categoryMapper;
    @Resource
    RedisTemplate redisTemplate;
    /*
        缓存管理的业务基本一致：
                大量的使用缓存管理，代码冗余较多

                spring提供了自动缓存管理功能(aop):
           1、我们提供一个自动缓存管理器
                配置如何管理缓存(使用哪个中间件缓存数据、缓存时间、以及缓存策略..)
           2、在启动类启用spring缓存管理功能
           3、在需要缓存管理的方法上添加注解实现缓存管理(缓存的键)

     */
    // Cacheable: 业务方法执行前先查询缓存，如果没有调用业务方法并缓存返回结果，如果有直接返回缓存
    // product:cates::all

    @Cacheable(value = "product:cates" , key = "'all'")  // value是key的前缀，key支持表达式 拼接一个缓存的键
//            unless = "#result.size()==0")  unless用来写表达式：不需要缓存的返回结果表达式
    @Override
    public List<CategoryVo> findCategoryTree() {
        //如果没有缓存：查询数据库数据存到缓存中
        List<CategoryVo> categoryVoList = categoryMapper.findAll();
        //挑出1级分类集合
        List<CategoryVo> parents = categoryVoList.stream().filter(categoryVo -> categoryVo.getParentId().equals(0L))
                .collect(Collectors.toList());
        //递归给每个父分类查找下一级组装
        buildCategoryTree(parents , categoryVoList);
        return parents;
    }


//    @Override
//    public List<CategoryVo> findCategoryTree() {
//        //查询缓存：如果有直接返回
//        Object o = redisTemplate.opsForValue().get("product:cates:all");
//        if(o!=null){
//            return (List<CategoryVo>) o;
//        }
//
//        //如果没有缓存：查询数据库数据存到缓存中
//        List<CategoryVo> categoryVoList = categoryMapper.findAll();
//        //挑出1级分类集合
//        List<CategoryVo> parents = categoryVoList.stream().filter(categoryVo -> categoryVo.getParentId().equals(0L))
//                .collect(Collectors.toList());
//        //递归给每个父分类查找下一级组装
//        buildCategoryTree(parents , categoryVoList);
//
//
//        //保存数据到缓存中
//        redisTemplate.opsForValue().set("product:cates:all" , parents ,
//                600 , TimeUnit.SECONDS);
//        return parents;
//    }

    //构建分类的树形数据
    private void buildCategoryTree(List<CategoryVo> parents ,List<CategoryVo> all){
        if(CollectionUtils.isEmpty(parents)){
            return;
        }
        parents.forEach(parent->{
            //给父分类挑选子分类
            List<CategoryVo> children = all.stream().filter(categoryVo ->
                            categoryVo.getParentId().equals(parent.getId()))
                    .collect(Collectors.toList());
            if(!CollectionUtils.isEmpty(children)){
                parent.setChildren(children);
            }
            buildCategoryTree(children , all);
        });
    }
}
